package com.xjgzinfo.usdp.service;

import com.xjgzinfo.usdp.domain.BladeVisual;
import com.xjgzinfo.usdp.domain.BladeVisual_;
import com.xjgzinfo.usdp.jpa.service.QueryService;
import com.xjgzinfo.usdp.repository.BladeVisualRepository;
import com.xjgzinfo.usdp.service.dto.BladeVisualCriteria;
import com.xjgzinfo.usdp.service.dto.BladeVisualDTO;
import com.xjgzinfo.usdp.service.mapper.BladeVisualMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * Service for executing complex queries for {@link BladeVisual} entities in the database.
 * The main input is a {@link BladeVisualCriteria} which gets converted to {@link Specification},
 * in a way that all the filters must apply.
 * It returns a {@link List} of {@link BladeVisualDTO} or a {@link Page} of {@link BladeVisualDTO} which fulfills the criteria.
 */
@Service
@Transactional(readOnly = true)
public class BladeVisualQueryService extends QueryService<BladeVisual> {

    private final Logger log = LoggerFactory.getLogger(BladeVisualQueryService.class);

    private final BladeVisualRepository bladeVisualRepository;

    private final BladeVisualMapper bladeVisualMapper;

    public BladeVisualQueryService(BladeVisualRepository bladeVisualRepository, BladeVisualMapper bladeVisualMapper) {
        this.bladeVisualRepository = bladeVisualRepository;
        this.bladeVisualMapper = bladeVisualMapper;
    }

    /**
     * Return a {@link List} of {@link BladeVisualDTO} which matches the criteria from the database.
     *
     * @param criteria The object which holds all the filters, which the entities should match.
     * @return the matching entities.
     */
    @Transactional(readOnly = true)
    public List<BladeVisualDTO> findByCriteria(BladeVisualCriteria criteria) {
        log.debug("find by criteria : {}", criteria);
        final Specification<BladeVisual> specification = createSpecification(criteria);
        return bladeVisualMapper.toDto(bladeVisualRepository.findAll(specification));
    }

    /**
     * Return a {@link Page} of {@link BladeVisualDTO} which matches the criteria from the database.
     *
     * @param criteria The object which holds all the filters, which the entities should match.
     * @param page     The page, which should be returned.
     * @return the matching entities.
     */
    @Transactional(readOnly = true)
    public Page<BladeVisualDTO> findByCriteria(BladeVisualCriteria criteria, Pageable page) {
        log.debug("find by criteria : {}, page: {}", criteria, page);
        final Specification<BladeVisual> specification = createSpecification(criteria);
        return bladeVisualRepository.findAll(specification, page)
                .map(bladeVisualMapper::toDto);
    }

    /**
     * Return the number of matching entities in the database.
     *
     * @param criteria The object which holds all the filters, which the entities should match.
     * @return the number of matching entities.
     */
    @Transactional(readOnly = true)
    public long countByCriteria(BladeVisualCriteria criteria) {
        log.debug("count by criteria : {}", criteria);
        final Specification<BladeVisual> specification = createSpecification(criteria);
        return bladeVisualRepository.count(specification);
    }

    /**
     * Function to convert {@link BladeVisualCriteria} to a {@link Specification}
     *
     * @param criteria The object which holds all the filters, which the entities should match.
     * @return the matching {@link Specification} of the entity.
     */
    protected Specification<BladeVisual> createSpecification(BladeVisualCriteria criteria) {
        Specification<BladeVisual> specification = Specification.where(null);
        if (criteria != null) {
            if (criteria.getId() != null) {
                specification = specification.and(buildRangeSpecification(criteria.getId(), BladeVisual_.id));
            }
            if (criteria.getCategory() != null) {
                specification = specification.and(buildRangeSpecification(criteria.getCategory(), BladeVisual_.category));
            }
            if (criteria.getTitle() != null) {
                specification = specification.and(buildStringSpecification(criteria.getTitle(), BladeVisual_.title));
            }
            if (criteria.getUpdateUser() != null) {
                specification = specification.and(buildRangeSpecification(criteria.getUpdateUser(), BladeVisual_.updateUser));
            }
            if (criteria.getPassword() != null) {
                specification = specification.and(buildStringSpecification(criteria.getPassword(), BladeVisual_.password));
            }
            if (criteria.getCreateUser() != null) {
                specification = specification.and(buildRangeSpecification(criteria.getCreateUser(), BladeVisual_.createUser));
            }
            if (criteria.getUpdateTime() != null) {
                specification = specification.and(buildRangeSpecification(criteria.getUpdateTime(), BladeVisual_.updateTime));
            }
            if (criteria.getCreateDept() != null) {
                specification = specification.and(buildRangeSpecification(criteria.getCreateDept(), BladeVisual_.createDept));
            }
            if (criteria.getCreateTime() != null) {
                specification = specification.and(buildRangeSpecification(criteria.getCreateTime(), BladeVisual_.createTime));
            }
            if (criteria.getStatus() != null) {
                specification = specification.and(buildRangeSpecification(criteria.getStatus(), BladeVisual_.status));
            }
            if (criteria.getIsDeleted() != null) {
                specification = specification.and(buildRangeSpecification(criteria.getIsDeleted(), BladeVisual_.isDeleted));
            }
        }
        return specification;
    }
}